package org.jeecg.modules.demo.util;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.jeecg.common.util.MinioUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.*;

/**
 * @program: ipds
 * @description: Freemarker工具类
 * @author: zhang
 * @date: 2024-03-28 21:22
 **/
@Slf4j
public class FreemarkerUtils {

    private static final String PATH = "opt/upFiles/templates/word";
    // private static final String PATH = FreemarkerUtils.class.getResource("/templates/word").getPath();

    /**
     * 生成Word
     * @param templateName  模板文件名称
     * @param filename      生成的文件（含路径）
     * @param dataModel     模板参数数据
     */
    public static String generateWord(String templateName, String filename, Object dataModel, HttpServletRequest request, HttpServletResponse response) {
        OutputStreamWriter writer = null;
        ByteArrayInputStream bais= null;
        POIFSFileSystem poifs= null;
        // ServletOutputStream ostream= null;
        ByteArrayOutputStream outputStream = null;
        try {
//            response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
//            response.setContentType("application/msword");
//            response.setHeader("content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()))));
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_30);
            configuration.setDefaultEncoding("UTF-8");
//            String templateFolder2 = "/templates/word" + File.separator;
//            String path = new ClassPathResource("classpath:templates/word").getPath();
//
//            log.info("<<模板存放地址>>"+path);
            configuration.setDirectoryForTemplateLoading(new File(PATH));

            Template template = configuration.getTemplate(templateName);
            // 使用StringWriter捕获模板输出
            Writer out = new StringWriter();
            template.process(dataModel, out);
            // writer = new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8);
            // template.process(dataModel, writer);
            String context = out.toString();
            byte[] b = context.getBytes("GBK"); //这里是必须要设置编码的，不然导出中文就会乱码。
            bais = new ByteArrayInputStream(b);//将字节数组包装到流中
            poifs = new POIFSFileSystem();
            outputStream = new ByteArrayOutputStream();
            DirectoryEntry directory = poifs.getRoot();
            DocumentEntry documentEntry = directory.createDocument("WordDocument", bais); //该步骤不可省略，否则会出现乱码。
            // 输出文件
            // ostream = response.getOutputStream();
            poifs.writeFilesystem(outputStream);
            return MinioUtil.upload( new ByteArrayInputStream(outputStream.toByteArray()),filename);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (TemplateNotFoundException e) {
            throw new RuntimeException(e);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        } catch (MalformedTemplateNameException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if(writer != null) {
                    writer.close();
                }
                if(bais != null){
                    bais.close();
                }
                if(poifs != null){
                    poifs.close();
                }
                if(outputStream != null){
                    outputStream.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
